package com.earth.quake.enhancement;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.lang.Math;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Point;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;

public class EarthquakedbenhancementActivity extends MapActivity {
	
	 ListView earthquakeListView;
	 ArrayAdapter<EQuake> aa;
	 EQuake selectedQuake;
 	 ArrayList<EQuake> equakes = new ArrayList<EQuake>();
 	
	 static final private int MENU_UPDATE = Menu.FIRST;
	 static final private int MENU_PREFERENCES = Menu.FIRST+1;
	 private static final int SHOW_PREFERENCES = 1;
	 static final private int QUAKE_DIALOG = 1;
	 int minimumMagnitude = 0;
	 boolean autoUpdate = false;
	 int updateFreq = 0;
	 String sel_Location = null;
	 
	 
	MapView mapView; 

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
    	
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        mapView = (MapView) findViewById(R.id.mapView);
        mapView.setBuiltInZoomControls(true);
        mapView.setSatellite(true);
        earthquakeListView = (ListView)this.findViewById(R.id.equakeListView);

    //	int layoutID = android.R.layout.simple_list_item_1;
    //	aa = new ArrayAdapter<EQuake>(this, layoutID , equakes);
    //	earthquakeListView.setAdapter(aa);
    	 
     //   refreshEarthquakes();
        updateFromPreferences();
        displayQuakes();
        
        mapView.setBuiltInZoomControls(true);
        mapView.setSatellite(true);
        MapController mapController = mapView.getController();
        mapController.setZoom(3);
        List<Overlay> mapOverlays = mapView.getOverlays();
        Drawable drawable = this.getResources().getDrawable(R.drawable.marker);
        CustomizedOverlay itemizedOverlay = new CustomizedOverlay(drawable, this);
                
        for(int i=0; i<equakes.size(); i++){
        	System.out.println("Latitude: "+(int)equakes.get(i).getLocation().getLatitude()+"\n");
        	System.out.println("Longitude: "+(int)equakes.get(i).getLocation().getLongitude()+"\n");
        	OverlayItem j = new OverlayItem( new GeoPoint((int)(equakes.get(i).getLocation().getLatitude()*1000000),
        			(int)(equakes.get(i).getLocation().getLongitude()*1000000)), equakes.get(i).getDetails(),equakes.get(i).getLink());
           	itemizedOverlay.addOverlay(j);           
        } 
    
     // Display all three items at once
    /*    for(int i=0; i<equakes.size(); i++){
        	System.out.println("Inside loop i:"+i);        	
           	itemizedOverlay.addOverlay(new OverlayItem( new GeoPoint((int)equakes.get(i).getLocation().getLatitude(),(int)equakes.get(i).getLocation().getLongitude()), equakes.get(i).getDetails(), "Food snippet 1"));           
        } */
        mapOverlays.add(itemizedOverlay);
        mapView.postInvalidate();
    }
    
    private void displayQuakes() {
		// TODO Auto-generated method stub
    	ContentResolver cr = getContentResolver();
	      // Clear the old earthquakes
    	equakes.clear();
    	  // If the earthquake is new, insert it into the provider.
    	  Cursor cursor = cr.query(QuakeProvider.CONTENT_URI, null, null, null, null);
    	  if(cursor!=null){
    		  if (cursor.getCount()!=0){
    			  while (cursor.moveToNext()) {
	    				long dateString = cursor.getLong(QuakeProvider.DATE_COLUMN);
	    				Date date = new Date(dateString);
		    			String details = cursor.getString(QuakeProvider.DETAILS_COLUMN);
		    			Double longitude  = cursor.getDouble(QuakeProvider.LONGITUDE_COLUMN);
		    			Double latitude = cursor.getDouble(QuakeProvider.LATITUDE_COLUMN);
		    			Double magnitude = cursor.getDouble(QuakeProvider.MAGNITUDE_COLUMN);
		    			String link = cursor.getString(QuakeProvider.LINK_COLUMN);
	  	    	        
		    			Location l = new Location("dummyGPS");
		      	        l.setLatitude(latitude);
		      	        l.setLongitude(longitude);
		      	        
		      	        EQuake equake = new EQuake();
		      	        equake.setLocation(l);    	    			
		    			equake.setDetails(details);
		    			equake.setLink(link);
		    			equake.setMagnitude(magnitude);
		    			equake.setDate(date);
		    		
		    			if (equake.getMagnitude() > minimumMagnitude) {
		    				equakes.add(equake);
		    			    // Notify the array adapter of a change.
		    			 //  aa.notifyDataSetChanged();
	    		          
		    			}
		    		/*	 if(sel_Location != null){
		    				String[] loc;
		    				 
		    				  // delimiter 
		    				  String delimiter = ",";
		    				 // given string will be split by the argument delimiter provided. 
		    				  loc = sel_Location.split(delimiter);
		    				 
		    				  Double lat = Double.parseDouble(loc[0]);
		    				  Double lon = Double.parseDouble(loc[1]);
		    				  if(((latitude) >= (lat - 1.00) && (latitude) <= (lat + 1.00)) && ((longitude) >= (lon - 1.00)&& (longitude) <= (lon + 1.00))){
		    				  // Add the new quake to our list of earthquakes.
		    					    equakes.add(equake);
		    					    // Notify the array adapter of a change.
		    					  //  aa.notifyDataSetChanged();
		    				  }
		    				  
		    			} */
		    			if(cursor.isLast())
		    				break;
    			  }
    		  }
    		  cursor.close();
    	 }
    	          
    	  earthquakeListView.setOnItemClickListener(new OnItemClickListener() {
    	        @Override
    	        public void onItemClick(AdapterView _av, View _v, int _index,
    	           long arg3) {
    	          selectedQuake = equakes.get(_index);
    	          showDialog(QUAKE_DIALOG);
    	        }
    	   });
    	
	}

	private void refreshEarthquakes() {
      ArrayList<EQuake> earthquakes = new ArrayList<EQuake>();
  	  // Get the XML
  	  URL url;
  	  try {
  	    String quakeFeed = getString(R.string.quake_feed);
  	    url = new URL(quakeFeed);

  	    URLConnection connection;
  	    connection = url.openConnection();

  	    HttpURLConnection httpConnection = (HttpURLConnection)connection;
  	    int responseCode = httpConnection.getResponseCode();

  	    if (responseCode == HttpURLConnection.HTTP_OK) {
  	      InputStream in = httpConnection.getInputStream();

  	      DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
  	      DocumentBuilder db = dbf.newDocumentBuilder();

  	      // Parse the earthquake feed.
  	      Document dom = db.parse(in);
  	      Element docEle = dom.getDocumentElement();

  	      // Clear the old earthquakes
  	      earthquakes.clear();

  	      // Get a list of each earthquake entry.
  	      NodeList nl = docEle.getElementsByTagName("entry");
  	      if (nl != null && nl.getLength() > 0) {
  	        for (int i = 0 ; i < nl.getLength(); i++) {
  	          Element entry = (Element)nl.item(i);
  	          Element title = (Element)entry.getElementsByTagName("title").item(0);
  	          Element g = (Element)entry.getElementsByTagName("georss:point").item(0);
  	          Element when = (Element)entry.getElementsByTagName("updated").item(0);
  	          Element link = (Element)entry.getElementsByTagName("link").item(0);

  	          String details = title.getFirstChild().getNodeValue();
  	          String hostname = "http://earthquake.usgs.gov";
  	          String linkString = hostname + link.getAttribute("href");

  	          String point = g.getFirstChild().getNodeValue();
  	          String dt = when.getFirstChild().getNodeValue();
  	          SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss'Z'");
  	          Date qdate = new GregorianCalendar(0,0,0).getTime();
  	          try {
  	            qdate = sdf.parse(dt);
  	          } catch (ParseException e) {
  	            e.printStackTrace();
  	          }

  	          String[] location = point.split(" ");
  	          Location l = new Location("dummyGPS");
  	          l.setLatitude(Double.parseDouble(location[0]));
  	          l.setLongitude(Double.parseDouble(location[1]));

  	          String magnitudeString = details.split(" ")[1];
  	          int end =  magnitudeString.length()-1;
  	          double magnitude = Double.parseDouble(magnitudeString.substring(0, end));

  	          details = details.split(",")[1].trim();

  	          EQuake quake = new EQuake(qdate, details, l, magnitude, linkString);

  	         // addQuakeToArray(quake);
  	          // Process a newly found earthquake
  	          addNewQuake(quake, earthquakes);
  	        }
  	      }
  	    }
  	  } catch (MalformedURLException e) {
  	    e.printStackTrace();
  	  } catch (IOException e) {
  	    e.printStackTrace();
  	  } catch (ParserConfigurationException e) {
  	    e.printStackTrace();
  	  } catch (SAXException e) {
  	    e.printStackTrace();
  	  }
  	  finally {
  	  }
  	}
    
    private void addNewQuake(EQuake _quake, ArrayList<EQuake> earthquakes) {
  	  ContentResolver cr = getContentResolver();
  	  // Construct a where clause to make sure we don't already have this
  	  // earthquake in the provider.
  	  String w = QuakeProvider.KEY_DATE + " = " + _quake.getDate().getTime();

  	  // If the earthquake is new, insert it into the provider.
  	  Cursor cursor = cr.query(QuakeProvider.CONTENT_URI, null, w, null, null);
  	  if(cursor!=null){
  		  if (cursor.getCount()==0){
  		    ContentValues values = new ContentValues();
  	
  		    values.put(QuakeProvider.KEY_DATE, _quake.getDate().getTime());
  		    values.put(QuakeProvider.KEY_DETAILS, _quake.getDetails());
  		    double lat = _quake.getLocation().getLatitude();
  		    double lng = _quake.getLocation().getLongitude();
  		    values.put(QuakeProvider.KEY_LOCATION_LAT, lat);
  		    values.put(QuakeProvider.KEY_LOCATION_LNG, lng);
  		    values.put(QuakeProvider.KEY_LINK, _quake.getLink());
  		    values.put(QuakeProvider.KEY_MAGNITUDE, _quake.getMagnitude());
  	
  		    cr.insert(QuakeProvider.CONTENT_URI, values);
  		  }
  		  cursor.close();
  	 }
  	}

    private void updateFromPreferences() {
		Context context = getApplicationContext();
	      SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);

	      minimumMagnitude = Integer.parseInt(prefs.getString(QuakePreference.PREF_MIN_MAG, "0"));
	      updateFreq = Integer.parseInt(prefs.getString(QuakePreference.PREF_UPDATE_FREQ, "0"));
	      autoUpdate = prefs.getBoolean(QuakePreference.PREF_AUTO_UPDATE, false);
	      sel_Location = prefs.getString(QuakePreference.PREF_LOC_BASE, "0");
    }

    @Override
	public boolean onCreateOptionsMenu(Menu menu) {
	  super.onCreateOptionsMenu(menu);

	  menu.add(0, MENU_UPDATE, Menu.NONE, R.string.menu_update);
	  menu.add(0, MENU_PREFERENCES, Menu.NONE, R.string.menu_preferences);
	  return true;
	}

    public boolean onOptionsItemSelected(MenuItem item) {
  	  super.onOptionsItemSelected(item);

  	  switch (item.getItemId()) {
  	    case (MENU_UPDATE): {
  	      refreshEarthquakes();
  	      return true;
  	    }
  	    case (MENU_PREFERENCES): {
  	        Intent i = new Intent(this, QuakePreference.class);
  	        startActivityForResult(i, SHOW_PREFERENCES);
  	        return true;
  	      }
  	  }
  	  return false;
  	}
    
    @Override
	public Dialog onCreateDialog(int id) {
	  switch(id) {
	    case (QUAKE_DIALOG) :

	      LayoutInflater li = LayoutInflater.from(this);
	      View quakeDetailsView = li.inflate(R.layout.quakedetails, null);

	      AlertDialog.Builder quakeDialog = new AlertDialog.Builder(this);
	      quakeDialog.setTitle("Quake Time");
	      quakeDialog.setView(quakeDetailsView);
	      System.out.println("Before return\n");

	      return quakeDialog.create();
	  }
      System.out.println("after return\n");
	  return null;
	}
    
    @Override
	public void onPrepareDialog(int id, Dialog dialog) {
	  switch(id) {
	    case (QUAKE_DIALOG) :

	      SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
	      String dateString = sdf.format(selectedQuake.getDate());
	      String quakeText = "Magnitude " + selectedQuake.getMagnitude() +
	                         "\n" + selectedQuake.getDetails() + "\n" +
	                         selectedQuake.getLink();

	      AlertDialog quakeDialog = (AlertDialog)dialog;
	      quakeDialog.setTitle(dateString);
	      TextView detailstv = (TextView)quakeDialog.findViewById(R.id.quakeDetailTextView);
	      detailstv.setText(quakeText);
	      break;
	  }
	}

    @Override
	public void onActivityResult(int requestCode, int resultCode, Intent data) {
	  super.onActivityResult(requestCode, resultCode, data);

	  if (requestCode == SHOW_PREFERENCES)
	  //  if (resultCode == Activity.RESULT_OK) {
	    	//todo
	        updateFromPreferences();
	        displayQuakes();
	    	//refreshEarthquakes();
	 //   }
	}

	@Override
	protected boolean isRouteDisplayed() {
		// TODO Auto-generated method stub
		return false;
	}
}